package com.kitty.game.fight.factory.model;

import com.kitty.common.utils.SpringUtils;
import com.kitty.common.utils.PositionUtils;
import com.kitty.game.boss.config.BossSet;
import com.kitty.game.boss.model.BossFightParam;
import com.kitty.game.boss.model.BossParam;
import com.kitty.game.boss.model.SuperBossParam;
import com.kitty.game.config.GuardSet;
import com.kitty.game.fight.bean.*;
import com.kitty.game.fight.message.RespCombatFriends;
import com.kitty.game.fight.message.RespCombatOpponets;
import com.kitty.game.fight.message.RespRefreshPetList;
import com.kitty.game.fight.message.vo.FightMember;
import com.kitty.game.fight.message.vo.RefreshPet;
import com.kitty.game.fight.service.FightExecutorService;
import com.kitty.game.fight.service.FightMessageService;
import com.kitty.game.fight.service.FightService;
import com.kitty.game.guard.model.Guard;
import com.kitty.game.guard.service.GuardService;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.role.model.Role;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.team.model.Member;
import com.kitty.game.team.model.Team;
import com.kitty.mina.message.Message;
import com.kitty.mina.message.MessagePusher;
import lombok.Getter;
import lombok.Setter;
import org.nutz.lang.util.NutMap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;


@Getter
@Setter
public class NewBossFight extends Fight {


    private Role role;

    private Team team;

    private BossFightParam bossFightParam;

    private ArrayList<FightMember> fightMemberA = new ArrayList<>();

    private ArrayList<FightMember> fightMemberB = new ArrayList<>();

    public NewBossFight(int type, int mapId, Role role, Team team, BossFightParam bossFightParam) {
        super(type);
        this.mapId = mapId;
        this.role = role;
        this.team = team;
        this.bossFightParam = bossFightParam;
    }

    @Override
    public void loadActors() {
        List<Member> members = team.getList();
        ArrayList<Member> list = new ArrayList<>(members);
        int index = 0, petIndex = 5;
        FightService fightService = SpringUtils.getFightService();
        GuardService guardService = SpringUtils.getGuardService();

        List<FightObject> memberListA = getListA();

        int customIndex =0;
        for (Member member : list) {
            if (!member.isInTeam()) {
                continue;
            }
            FightExecutorService.FIGHT_ROOMS.put(member.getRoleId(), getId());
            Role teamRole = SpringUtils.getRoleService().getOnlinePlayer(member.getUid());
            if (teamRole == null) {
               // logger.error("进入战场未找到session=={}", member.getName());
                continue;
            }
            fightService.fullLifeRoleAndPet(teamRole);// 有储备情况下进战斗自动满血满蓝
            fightService.checkAtFightStart(teamRole);
            FightObject fightObject = new PlayerFightObject(teamRole,index, customIndex,true);
            ((PlayerFightObject) fightObject).setUseMonthTao(isUseMonth());
            memberListA.add(fightObject);

            FightMember fightMember = fightObject.asFightMember(getCustomIconListA());
            fightMemberA.add(fightMember);

            RespRefreshPetList respRefreshPetList = new RespRefreshPetList();
            RefreshPet refreshPet = new RefreshPet();
            ArrayList<RefreshPet> refreshPets = new ArrayList<>();
            refreshPets.add(refreshPet);
            refreshPet.setPetId(teamRole.getPetBox().getFightPetId());
            respRefreshPetList.setPetList(refreshPets);
            MessagePusher.pushMessage(teamRole, respRefreshPetList);

            index++;
            customIndex++;
            Pet pet = SpringUtils.getPetService().getPetById(teamRole.getPetBox().getFightPetId(), teamRole);
            if (pet != null && pet.canJoinFight()) {
                customIndex++;
                PetFightObject petFightObj = new PetFightObject(pet, fightObject, PositionUtils.positions.get(petIndex));
                memberListA.add(petFightObj);
                FightMember petFightMember = petFightObj.asFightMember();
                fightMemberA.add(petFightMember);
                FightExecutorService.PETID_ROLEID.put(pet.getId(), member.getRoleId());
                FightExecutorService.FIGHT_ROOMS.put(pet.getId(), getId());
            }else if(pet!=null){
                MessagePusher.pushMessage(teamRole,new RespMsg("你当前参战宠物的#R忠诚度#n太低了，当宠物的忠诚小于等于70时有一定几率不参加战斗！"));
            }
            petIndex++;
        }

        // 加载守护
        if (bossFightParam.isLoadGuard() && fightService.isGuardJoinFight(getType()) && index < 5) {
            Role leader = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            for (Member member : team.getShouhus()) {
                if (leader == null) {
                    continue;
                }
                Guard guard = guardService.getGuard(member.getRoleId(), leader);
                if (guard == null) {
                    continue;
                }
                if (guard.getIsFight() != 1) {
                    continue;
                }
                GuardSet guardSet = guardService.getGuardSet(guard.getName());
                FightObject fightObject = new GuardFightObject(guard, guardSet, PositionUtils.positions.get(index), true);
                memberListA.add(fightObject);
                FightMember fightMember = fightObject.asFightMember();
                fightMemberA.add(fightMember);
                index++;
                if (index >= 5) {
                    break;
                }
            }
        }
    }

    @Override
    public void notifyAndStart() {
        RespCombatFriends respCombatFriends = new RespCombatFriends();
        respCombatFriends.setCustomIconList(getCustomIconListA());

        RespCombatOpponets respCombatOpponets = new RespCombatOpponets();
        respCombatOpponets.setCustomIconList(getCustomIconListB());


        int index = 0;
        List<FightObject> memberListB = getListB();
        int monsterId = 567898745;
        List<BossParam> bossParamList = bossFightParam.getBossParamList();
        setBossReward(new NutMap());
        getBossReward().setv("size", bossParamList.size());
        if (bossFightParam.getReward() != null) {
            getBossReward().putAll(bossFightParam.getReward());
        }
        for (BossParam bossParam : bossParamList) {
            BossSet bossSet = bossParam.getBossSet();
            getBossReward().setv("rewardExp",
                    getBossReward().getInt("rewardExp", 0) + bossSet.getRewardExp());
            getBossReward().setv("rewardDaijinquan",
                    getBossReward().getInt("rewardDaijinquan", 0) + bossSet.getRewardDaijinquan());
            getBossReward().setv("rewardDaohang",
                    getBossReward().getInt("rewardDaohang", 0) + bossSet.getRewardDaohang());
            getBossReward().setv("rewardMoney",
                    getBossReward().getInt("rewardMoney", 0) + bossSet.getRewardMoney());
            getBossReward().setv("rewardQianneng",
                    getBossReward().getInt("rewardQianneng", 0) + bossSet.getRewardQianneng());
            getBossReward().setv("petRewardWuxue",
                    getBossReward().getInt("petRewardWuxue", 0) + bossSet.getPetRewardWuxue());

            short level = (bossFightParam.getNpcLevel() > 0 ? bossFightParam.getNpcLevel() :  role.getLevel());
            FightObject fightObject = null;
            boolean superBossZP = bossParam.isSuperBossZP();
            boolean superBossZP1 = bossParam.isSuperBossZP();
            if (bossParam.isSuperBoss()) {
                SuperBossParam superBossParam = (SuperBossParam)bossParam;
                if (superBossParam.getMainShowAfterRound() > 0) {
                    if (getData() == null) {setData(NutMap.NEW());}
                    getData().put("fight_main_show_after_round", superBossParam.getMainShowAfterRound());
                    getData().put("fight_super_boss_param", superBossParam);
                    if (superBossParam.getCallShowSmallAfterRound() > 0) {
                        getData().put("fight_call_show_small_after_round", superBossParam.getCallShowSmallAfterRound());
                        getData().put("fight_call_show_small_name", bossParam.getName());
                    }
                    continue;
                } else {
                    fightObject = new SuperBossFightObject(bossSet, bossParam, PositionUtils.positions.get(index), monsterId, level);
                    //logger.error("初始化战斗对象=世界boss=={}",bossSet.getName());
                }
                if (superBossParam.getSmallEscapeAfterRound() > 0) {
                    getData().put("fight_small_escape_after_round", superBossParam.getSmallEscapeAfterRound());
                }
            } else if (bossParam.isSuperBossZP()) {
                if (index < 5) {
                    index = 5;
                }
                fightObject = new SuperBossZPFightObject(bossSet, bossParam, PositionUtils.positions.get(index), monsterId, level);
            } else {
                if (getData() == null) {setData(NutMap.NEW());}
                if(bossParam.isRefreshsmallname()){
                    getData().put("fight_npc_boss_refresh", true);
                    getData().setv("fight_round_start_shouting", Arrays.asList("123"));
                    getData().put("fight_npc_boss_refresh_name", bossParam.getName());
                }
                fightObject = new BossFightObject(bossSet, bossParam, PositionUtils.positions.get(index), monsterId, level);
            }
            changeFightObject(fightObject, bossParam);
            memberListB.add(fightObject);
            FightMember fightMember = fightObject.asFightMember();
            changeFightMember(fightMember, bossParam);
            fightMemberB.add(fightMember);
            index++;
            monsterId++;
        }
        respCombatOpponets.setList(fightMemberB);
        respCombatFriends.setList(fightMemberA);
        setListB(memberListB);

        FightService fightService = SpringUtils.getFightService();
        ArrayList<Member> list = new ArrayList<>(team.getList());
        fightService.sendStartCombat(respCombatFriends, respCombatOpponets, list);
        fightService.whileSendStart(this);

        /**喊话*/
        if (bossFightParam.getShoutingList() != null) {
            if (bossFightParam.getShoutingList().size() > 1) {
                ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
                List<FightObject> tempMemberListB = new ArrayList<>(memberListB);
                for (String shouting : bossFightParam.getShoutingList()) {
                    int tempIndex = threadLocalRandom.nextInt(tempMemberListB.size());
                    FightObject tempObject = tempMemberListB.remove(tempIndex);
                    Message message = SpringUtils.getBean(FightMessageService.class).fightMsg(tempObject, shouting);
                    SpringUtils.getTeamService().pushMessageToTeam(team, message);
                }
            } else {
                String shouting = bossFightParam.getShoutingList().get(0);
                FightObject fightObject = memberListB.get(0);
                Message message = SpringUtils.getBean(FightMessageService.class).fightMsg(fightObject, shouting);
                SpringUtils.getTeamService().pushMessage(role, message);
            }
        }

        for (FightObject fightObject : getListA()) {
            if (fightObject.isPlayer()) {
                fightService.autoFightOne(this, fightObject);
            }

        }
    }


    /**
     * 根据传入的BossParam改变FightObject的一些值
     */
    private void changeFightObject(FightObject fightObject, BossParam bossParam) {
        if (bossParam.getPolar() > 0) {
            fightObject.setPolar(bossParam.getPolar());
        }
        if (bossParam.getSkillIds() != null) {
            fightObject.setSkillIds(bossParam.getSkillIds());
        }
    }

    /**
     * 根据传入的BossParam改变FightMember的一些值
     */
    private void changeFightMember(FightMember fightMember, BossParam bossParam) {
        if (bossParam.getIcon() > 0) {
            fightMember.setIcon(bossParam.getIcon());
        }
        if (bossParam.getSuitIcon() > 0) {
            fightMember.setSuit_icon(bossParam.getSuitIcon());
        }

        if (bossParam.getSuitLightEffect() > 0) {
            fightMember.setSuit_light_effect(bossParam.getSuitLightEffect());
        }
    }

    public FightObject addFightObject(BossParam bossParam, byte index) {
        BossSet bossSet = bossParam.getBossSet();
        short level = (bossFightParam.getNpcLevel() > 0 ? bossFightParam.getNpcLevel() :  role.getLevel());
        int monsterId = getMaxFightObjectId() + 1;
        FightObject fightObject = null;
        if (bossParam.isSuperBoss()) {
            fightObject = new SuperBossFightObject(bossSet, bossParam, PositionUtils.positions.get(index), monsterId, level);
        } else if (bossParam.isSuperBossZP()) {
            fightObject = new SuperBossZPFightObject(bossSet, bossParam, PositionUtils.positions.get(index), monsterId, level);
        } else if (bossParam.isSuperBossZPJS()) {
            fightObject = new SuperBossZPJSFightObject(bossSet, bossParam, PositionUtils.positions.get(index), monsterId, level);
        }  else {
            fightObject = new BossFightObject(bossSet, bossParam, PositionUtils.positions.get(index), monsterId, level);
        }
        changeFightObject(fightObject, bossParam);
        List<FightObject> memberListB = getListB();
        memberListB.add(fightObject);
        FightMember fightMember = fightObject.asFightMember();
        changeFightMember(fightMember, bossParam);
        fightMemberB.add(fightMember);

        return fightObject;
    }
}
